#ifndef METADATAOPERACION_H
#define METADATAOPERACION_H

#include <list>
#include <vector>
#include <fstream>
#include <string>
#include "Operacion.h"
#include "ArchivoRF.h"
#include "../Comun/MetadataClase.h"
#include "HidratadorMetadataClase.h"

using namespace std;

namespace CapaIndices
{
	
	enum OpTipo{
		iBorrado,
		iSeleccion,
		iInsercion,
		iActualizacion,
		iExisteClase,
		iGetMetadataClase,
		iAltaClase
	};
	
	enum OpTipoCondicion{
		iAnd,
		iOr
	};
	
	class CondicionOperacion{
		private:
			string _Atributo;
			TipoSimbolo _Operador;
			string _Valor;
	
		public:
			void setAtributo(string atr){
				_Atributo=atr;
			}
	
			string getAtributo(){
				return _Atributo;
			}
	
			void setOperador(TipoSimbolo op){
				_Operador=op;
			}
	
			TipoSimbolo getOperador(){
				return _Operador;
			}
			void setValor(string val){
				_Valor=val;
			}
			
			string getValor(){
				return _Valor;
			}
	
	};
	
	class MetadataOperacion
	{
		private:
			string _Clase;
			OpTipo _TipoOperacion;
			OpTipoCondicion _TipoCondicion;
			list<CondicionOperacion> _Condiciones;
			list<ClaveValor> _Datos;
			list<string> _ColumnasSeleccion;
			list<string> _MetadataClaseDeshidratada;		
			
			MetadataOperacion();
	
			void setOperacion(OpTipo Tipo);
	
			void setClase(string Clase);
	
			void setTipoCondicion(OpTipoCondicion TipoCondicion);
	
			void addCondicion(const CondicionOperacion& Cond);
	
			void addDato(const ClaveValor& Dat);
	
			void addColumnaSeleccion(const string& str);
	
			void addLineaMetadataClase(const string& str);
	
		public:
	
			MetadataClase* _LaMetadataDeLaClase;
	
			OpTipo getOperacion();
	
			string getClase();
	
	
			OpTipoCondicion getTipoCondicion();
	
			list<CondicionOperacion> getCondiciones();
	
			list<ClaveValor>& getDatos();
	
			list<string>* getColumnasSeleccion();
	
			list<string>* getMetadataClaseStream();
	
			~MetadataOperacion();
	
			static MetadataOperacion* hidratar(fstream& StreamContacto);
	
			Operacion* generarOperacion();
	
		private:
	
			MetadataClase* RecuperarMetadata();
	
			void GuardarMetadata();
	
		private:
			CondicionCompuesta* getCondicionCompuestaFormatoComun();
	
			Condicion* getCondicionFormatoComun(CondicionOperacion& CO);
	
			TipoRegistro getTipoAtributo(string Atrib);
	
			Condicion* getCondicionTipo(TipoSimbolo OP);
	
			static OpTipo hidratarTipoOperacion(string str);
	
			static CondicionOperacion hidratarCondicion(string val[]);
	
			static ClaveValor hidratarDatos(string val[]);
	
			static string hidratarNombreClase(string str);
	
			static TipoSimbolo hidratarOperador(string str);
	
			static OpTipoCondicion hidratarTipoCondicion(string str);
	
	};

}

#endif
